home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / Mesa-3.0 / BeOS / SELECT.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-03  |  10.7 KB  |  582 lines

  1. /* generic.c */
  2.  
  3. /* Demo of BEOS Mesa rendering */
  4.  
  5. /*
  6.  * See Mesa/include/GL/osmesa.h for documentation of the OSMesa functions.
  7.  *
  8.  * If you want to render BIG images you'll probably have to increase
  9.  * MAX_WIDTH and MAX_HEIGHT in src/config.h.
  10.  *
  11.  * This program is in the public domain.
  12.  *
  13.  * BEOS output provided by Tinic Urou
  14.  * 5uro@informatik.uni-hamburg.de
  15.  */
  16.  
  17. #include <AppKit.h>
  18. #include <InterfaceKit.h>
  19. #include <KernelKit.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <math.h>
  24. #include "GL/osmesa.h"
  25. #include "GL/glu.h"
  26.  
  27.  
  28. #define MAXOBJS 10000
  29. #define MAXSELECT 100
  30. #define MAXFEED 300
  31. #define    SOLID 1
  32. #define    LINE 2
  33. #define    POINT 3
  34.  
  35.  
  36. GLenum directRender;
  37. GLint windW, windH;
  38.  
  39. GLuint selectBuf[MAXSELECT];
  40. GLfloat feedBuf[MAXFEED];
  41. GLint vp[4];
  42. float zRotation = 90.0;
  43. float zoom = 1.0;
  44. GLint objectCount;
  45. GLint numObjects;
  46. struct object {
  47.     float v1[2];
  48.     float v2[2];
  49.     float v3[2];
  50.     float color[3];
  51. } objects[MAXOBJS];
  52. GLenum linePoly = GL_FALSE;
  53.  
  54.  
  55. static void InitObjects(GLint num)
  56. {
  57.     GLint i;
  58.     float x, y;
  59.  
  60.     if (num > MAXOBJS) {
  61.     num = MAXOBJS;
  62.     }
  63.     if (num < 1) {
  64.     num = 1;
  65.     }
  66.     objectCount = num;
  67.  
  68.     srand((unsigned int)time(NULL));
  69.     for (i = 0; i < num; i++) {
  70.     x = (rand() % 300) - 150;
  71.     y = (rand() % 300) - 150;
  72.  
  73.     objects[i].v1[0] = x + (rand() % 50) - 25;
  74.     objects[i].v2[0] = x + (rand() % 50) - 25;
  75.     objects[i].v3[0] = x + (rand() % 50) - 25;
  76.     objects[i].v1[1] = y + (rand() % 50) - 25;
  77.     objects[i].v2[1] = y + (rand() % 50) - 25;
  78.     objects[i].v3[1] = y + (rand() % 50) - 25;
  79.     objects[i].color[0] = ((rand() % 100) + 50) / 150.0;
  80.     objects[i].color[1] = ((rand() % 100) + 50) / 150.0;
  81.     objects[i].color[2] = ((rand() % 100) + 50) / 150.0;
  82.     }
  83. }
  84.  
  85. static void Init(void)
  86. {
  87.  
  88.     numObjects = 10;
  89.     InitObjects(numObjects);
  90.     glGetIntegerv(GL_VIEWPORT, vp);
  91. }
  92.  
  93. static void Reshape(int width, int height)
  94. {
  95.  
  96.     windW = (GLint)width;
  97.     windH = (GLint)height;
  98. }
  99.  
  100. static void Render(GLenum mode)
  101. {
  102.     GLint i;
  103.  
  104.     for (i = 0; i < objectCount; i++) {
  105.     if (mode == GL_SELECT) {
  106.         glLoadName(i);
  107.     }
  108.     glColor3fv(objects[i].color);
  109.     glBegin(GL_POLYGON);
  110.         glVertex2fv(objects[i].v1);
  111.         glVertex2fv(objects[i].v2);
  112.         glVertex2fv(objects[i].v3);
  113.     glEnd();
  114.     }
  115. }
  116.  
  117. static GLint DoSelect(GLint x, GLint y)
  118. {
  119.     GLint hits;
  120.  
  121.     glSelectBuffer(MAXSELECT, selectBuf);
  122.     (void)glRenderMode(GL_SELECT);
  123.     glInitNames();
  124.     glPushName(~0);
  125.  
  126.     glPushMatrix();
  127.  
  128.     glViewport(0, 0, windW, windH);
  129.     glGetIntegerv(GL_VIEWPORT, vp);
  130.  
  131.     glMatrixMode(GL_PROJECTION);
  132.     glLoadIdentity();
  133.     gluPickMatrix(x, windH-y, 4, 4, vp);
  134.     gluOrtho2D(-175, 175, -175, 175);
  135.     glMatrixMode(GL_MODELVIEW);
  136.  
  137.     glClearColor(0.0, 0.0, 0.0, 0.0);
  138.     glClear(GL_COLOR_BUFFER_BIT);
  139.  
  140.     glScalef(zoom, zoom, zoom);
  141.     glRotatef(zRotation, 0, 0, 1);
  142.  
  143.     Render(GL_SELECT);
  144.  
  145.     glPopMatrix();
  146.     
  147.     hits = glRenderMode(GL_RENDER); 
  148.     if (hits <= 0) {
  149.     return -1;
  150.     }
  151.  
  152.     return selectBuf[(hits-1)*4+3];
  153. }
  154.  
  155. static void RecolorTri(GLint h)
  156. {
  157.  
  158.     objects[h].color[0] = ((rand() % 100) + 50) / 150.0;
  159.     objects[h].color[1] = ((rand() % 100) + 50) / 150.0;
  160.     objects[h].color[2] = ((rand() % 100) + 50) / 150.0;
  161. }
  162.  
  163. static void DeleteTri(GLint h)
  164. {
  165.  
  166.     objects[h] = objects[objectCount-1];
  167.     objectCount--;
  168. }
  169.  
  170. static void GrowTri(GLint h)
  171. {
  172.     float v[2];
  173.     float *oldV;
  174.     GLint i;
  175.  
  176.     v[0] = objects[h].v1[0] + objects[h].v2[0] + objects[h].v3[0];
  177.     v[1] = objects[h].v1[1] + objects[h].v2[1] + objects[h].v3[1];
  178.     v[0] /= 3;
  179.     v[1] /= 3;
  180.  
  181.     for (i = 0; i < 3; i++) {
  182.     switch (i) {
  183.       case 0:
  184.         oldV = objects[h].v1;
  185.         break;
  186.       case 1:
  187.         oldV = objects[h].v2;
  188.         break;
  189.       case 2:
  190.         oldV = objects[h].v3;
  191.         break;
  192.     }
  193.     oldV[0] = 1.5 * (oldV[0] - v[0]) + v[0];
  194.     oldV[1] = 1.5 * (oldV[1] - v[1]) + v[1];
  195.     }
  196. }
  197.  
  198. static void Draw(void)
  199. {
  200.  
  201.     glPushMatrix();
  202.  
  203.     glViewport(0, 0, windW, windH);
  204.     glGetIntegerv(GL_VIEWPORT, vp);
  205.  
  206.     glMatrixMode(GL_PROJECTION);
  207.     glLoadIdentity();
  208.     gluOrtho2D(-175, 175, -175, 175);
  209.     glMatrixMode(GL_MODELVIEW);
  210.  
  211.     glClearColor(0.0, 0.0, 0.0, 0.0);
  212.     glClear(GL_COLOR_BUFFER_BIT);
  213.  
  214.     glScalef(zoom, zoom, zoom);
  215.     glRotatef(zRotation, 0, 0, 1);
  216.  
  217.     Render(GL_RENDER);
  218.  
  219.     glPopMatrix();
  220.  
  221.     glFlush();
  222. }
  223.  
  224. static void DrawZoom(GLint x, GLint y)
  225. {
  226.  
  227.     glPushMatrix();
  228.  
  229.     glViewport(0, 0, windW, windH);
  230.     glGetIntegerv(GL_VIEWPORT, vp);
  231.  
  232.     glMatrixMode(GL_PROJECTION);
  233.     glLoadIdentity();
  234.     gluPickMatrix(x, windH-y, 4, 4, vp);
  235.     gluOrtho2D(-175, 175, -175, 175);
  236.     glMatrixMode(GL_MODELVIEW);
  237.  
  238.     glClearColor(0.0, 0.0, 0.0, 0.0);
  239.     glClear(GL_COLOR_BUFFER_BIT);
  240.  
  241.     glScalef(zoom, zoom, zoom);
  242.     glRotatef(zRotation, 0, 0, 1);
  243.  
  244.     Render(GL_RENDER);
  245.  
  246.     glPopMatrix();
  247. }
  248.  
  249. static void DumpFeedbackVert(GLint *i, GLint n)
  250. {
  251.     GLint index;
  252.  
  253.     index = *i;
  254.     if (index+7 > n) {
  255.     *i = n;
  256.     printf("  ???\n");
  257.     return;
  258.     }
  259.     printf("  (%g %g %g), color = (%4.2f %4.2f %4.2f)\n",
  260.        feedBuf[index],
  261.        feedBuf[index+1],
  262.        feedBuf[index+2],
  263.        feedBuf[index+3],
  264.        feedBuf[index+4],
  265.        feedBuf[index+5]);
  266.     index += 7;
  267.     *i = index;
  268. }
  269.  
  270. static void DrawFeedback(GLint n)
  271. {
  272.     GLint i;
  273.     GLint verts;
  274.  
  275.     printf("Feedback results (%d floats):\n", n);
  276.     for (i = 0; i < n; i++) {
  277.     switch ((GLint)feedBuf[i]) {
  278.       case GL_POLYGON_TOKEN:
  279.         printf("Polygon");
  280.         i++;
  281.         if (i < n) {
  282.         verts = (GLint)feedBuf[i];
  283.         i++;
  284.         printf(": %d vertices", verts);
  285.         } else {
  286.         verts = 0;
  287.         }
  288.         printf("\n");
  289.         while (verts) {
  290.         DumpFeedbackVert(&i, n);
  291.         verts--;
  292.         }
  293.         i--;
  294.         break;
  295.       case GL_LINE_TOKEN:
  296.         printf("Line:\n");
  297.         i++;
  298.         DumpFeedbackVert(&i, n);
  299.         DumpFeedbackVert(&i, n);
  300.         i--;
  301.         break;
  302.       case GL_LINE_RESET_TOKEN:
  303.         printf("Line Reset:\n");
  304.         i++;
  305.         DumpFeedbackVert(&i, n);
  306.         DumpFeedbackVert(&i, n);
  307.         i--;
  308.         break;
  309.       default:
  310.         printf("%9.2f\n", feedBuf[i]);
  311.         break;
  312.     }
  313.     }
  314.     if (i == MAXFEED) {
  315.     printf("...\n");
  316.     }
  317.     printf("\n");
  318. }
  319.  
  320. static void DoFeedback(void) 
  321. {
  322.     GLint x;
  323.  
  324.     glFeedbackBuffer(MAXFEED, GL_3D_COLOR, feedBuf);
  325.     (void)glRenderMode(GL_FEEDBACK);
  326.  
  327.     glPushMatrix();
  328.  
  329.     glViewport(0, 0, windW, windH);
  330.     glGetIntegerv(GL_VIEWPORT, vp);
  331.  
  332.     glMatrixMode(GL_PROJECTION);
  333.     glLoadIdentity();
  334.     gluOrtho2D(-175, 175, -175, 175);
  335.     glMatrixMode(GL_MODELVIEW);
  336.  
  337.     glClearColor(0.0, 0.0, 0.0, 0.0);
  338.     glClear(GL_COLOR_BUFFER_BIT);
  339.  
  340.     glScalef(zoom, zoom, zoom);
  341.     glRotatef(zRotation, 0, 0, 1);
  342.  
  343.     Render(GL_FEEDBACK);
  344.  
  345.     glPopMatrix();
  346.     
  347.     x = glRenderMode(GL_RENDER); 
  348.     if (x == -1) {
  349.     x = MAXFEED;
  350.     }
  351.  
  352.     DrawFeedback((GLint)x);
  353. }
  354.  
  355. static GLenum Args(int argc, char **argv)
  356. {
  357.     GLint i;
  358.  
  359.     directRender = GL_TRUE;
  360.  
  361.     for (i = 1; i < argc; i++) {
  362.     if (strcmp(argv[i], "-dr") == 0) {
  363.         directRender = GL_TRUE;
  364.     } else if (strcmp(argv[i], "-ir") == 0) {
  365.         directRender = GL_FALSE;
  366.     } else {
  367.         printf("%s (Bad option).\n", argv[i]);
  368.         return GL_FALSE;
  369.     }
  370.     }
  371.     return GL_TRUE;
  372. }
  373.  
  374. int                     gl_width=300,gl_height=300;
  375.  
  376. const     ulong             APP_SIGNATURE = '????';
  377. const     ulong            MSG_REDRAW = 1;
  378.  
  379. class                     MesaWindow;
  380. class                     MesaView;
  381. class                    MesaApp;
  382.  
  383. // Lets make our life easy and make them global:
  384.  
  385. BBitmap                 *the_bitmap;
  386. MesaView                *the_view;    
  387. MesaWindow                 *the_window;
  388.  
  389. class MesaView : public BView
  390. {
  391.     public:
  392.     
  393.     MesaView(BRect frame):BView(frame,"Mesa View",B_FOLLOW_NONE,B_WILL_DRAW)
  394.     {
  395.     };
  396.     
  397.     void MouseDown(BPoint pos)
  398.     {
  399.         GLint hit;
  400.         ulong button;
  401.  
  402.         Window()->Lock();
  403.         GetMouse(&pos,&button);
  404.         Window()->Unlock();
  405.  
  406.         hit = DoSelect((GLint)pos.x, (GLint)pos.y);
  407.             if (hit != -1) 
  408.         {
  409.             if (button & B_PRIMARY_MOUSE_BUTTON) 
  410.             {
  411.                 RecolorTri(hit);
  412.             }
  413.             if (button & B_SECONDARY_MOUSE_BUTTON) 
  414.             {
  415.                 GrowTri(hit);
  416.             }
  417.             if (button & B_TERTIARY_MOUSE_BUTTON) 
  418.             {
  419.                 DeleteTri(hit);
  420.             }
  421.         }
  422.      };
  423.     
  424.     void KeyDown(ulong aKey)
  425.     {
  426.         switch(aKey)
  427.         {
  428.             BPoint pos;
  429.             ulong buttons;
  430.  
  431.             case     B_LEFT_ARROW:
  432.                     zRotation += 0.5;
  433.                     break;
  434.               case     B_RIGHT_ARROW:
  435.                     zRotation -= 0.5;
  436.                     break;
  437.               case     'Z':
  438.                     zoom /= 0.75;
  439.                     break;
  440.               case     'z':
  441.                     zoom *= 0.75;
  442.                     break;
  443.               case     'f':
  444.                     DoFeedback();
  445.                     break;
  446.               case    'd':
  447.                     GetMouse(&pos,&buttons);
  448.                     DrawZoom((GLint)pos.x, (GLint)pos.y);
  449.                     break;
  450.               case     'l':
  451.                     linePoly = (GLenum)!linePoly;
  452.                     if (linePoly) 
  453.                     {
  454.                         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  455.                     } 
  456.                     else 
  457.                     {
  458.                         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  459.                     }
  460.                     break;
  461.         }
  462.     };
  463.     
  464.     void Draw(BRect frame)
  465.     {
  466.         DrawBitmap(the_bitmap,BPoint(0,0));
  467.     };                    
  468. };
  469.  
  470. class MesaWindow : public BWindow 
  471. {
  472.     public:
  473.     
  474.     MesaWindow(int width, int height):BWindow(BRect(0,0,width-1,height-1),"MesaView",B_TITLED_WINDOW,B_NOT_RESIZABLE|B_NOT_ZOOMABLE)
  475.     {
  476.         // Move window to right position
  477.         MoveTo(80, 24);
  478.         // Create bitmap view
  479.         Lock();
  480.         AddChild(the_view = new MesaView(BRect(0, 0, (gl_width)-1, (gl_height)-1)));
  481.         the_view->MakeFocus();
  482.         Unlock();
  483.     };
  484.     
  485.     void MessageReceived(BMessage *msg)
  486.     {
  487.         switch(msg->what)
  488.         {    
  489.             case    MSG_REDRAW:
  490.                     Lock();
  491.                     the_view->DrawBitmap(the_bitmap,BPoint(0,0));
  492.                     Draw();
  493.                     Unlock();
  494.                     PostMessage(MSG_REDRAW);
  495.                     break;
  496.             default:
  497.                     BWindow::MessageReceived(msg);
  498.                     break;
  499.         }
  500.     };
  501.     
  502.     bool QuitRequested(void)
  503.     {
  504.         be_app->PostMessage(B_QUIT_REQUESTED);
  505.         return TRUE;
  506.     };
  507. };
  508.  
  509. class MesaApp : public BApplication 
  510. {
  511.     OSMesaContext ctx;
  512.     
  513.     public:
  514.     
  515.     MesaApp():BApplication(APP_SIGNATURE)
  516.     {
  517.         the_window = NULL;
  518.         the_bitmap = NULL;
  519.     };
  520.             
  521.     void ReadyToRun(void)
  522.     {
  523.         // Allocate the bitmap        
  524.         the_bitmap = new BBitmap(BRect(0, 0, gl_width-1, gl_height-1), B_RGB_32_BIT);
  525.  
  526.         uchar *bits = (uchar *)the_bitmap->Bits();
  527.  
  528.         memset(bits,0,the_bitmap->BytesPerRow()*gl_height);
  529.  
  530.         // Open window
  531.         the_window = new MesaWindow((gl_width),(gl_height));
  532.         the_window->Show();
  533.  
  534.         unsigned char *buffer;
  535.         double start,end;
  536.  
  537.         // Create an RGBA-mode context 
  538.         ctx = OSMesaCreateContext( GL_RGBA, NULL );
  539.  
  540.         // Bind the buffer to the context and make it current */
  541.         OSMesaMakeCurrent( ctx, bits, GL_UNSIGNED_BYTE, gl_width, gl_height );
  542.         OSMesaPixelStore( OSMESA_Y_UP, 0 );
  543.  
  544.         Init();
  545.         Reshape(gl_width,gl_height);
  546.         the_window->PostMessage(MSG_REDRAW);    
  547.     };
  548.  
  549.     bool QuitRequested(void)
  550.     {
  551.         // Make sure that the window closes first
  552.         if (BApplication::QuitRequested()) 
  553.         {
  554.             OSMesaDestroyContext( ctx );
  555.             if (the_bitmap)    delete the_bitmap;
  556.             return TRUE;
  557.         }
  558.         return FALSE;
  559.     };
  560.             
  561.     void AboutRequested(void)
  562.     {
  563.         char str[256];
  564.         sprintf(str, "MesaDemos, ported by Tinic Urou\n<5uro@informatik.uni-hamburg.de>\nFreely distributable.");
  565.         BAlert *the_alert = new BAlert("", str, "OK");
  566.         the_alert->Go();
  567.     };
  568. };
  569.  
  570. int main( int argc, char *argv[] )
  571. {
  572.     MesaApp *the_app;
  573.  
  574.     Args(argc,argv);
  575.  
  576.     the_app = new MesaApp();
  577.     the_app->Run();
  578.     delete the_app;
  579.  
  580.     return 0;
  581. }
  582.